# The conceptual figures use random draws from SADs.
# Therefore they can look slightly different every time you run this script
##########################
# load packages and define some function
library(tidyverse)
library(vegan)
library(cowplot)
library(mobsim)
library(betaC)
rarefy_long <- function(x) {
if(is.matrix(x)==F) x=matrix(x,nrow = 1, byrow =T, dimnames= list("x", names(x)))
alphas <-
lapply(row.names(x), function(i)
return(as.numeric(vegan::rarefy(
x[i, ], sample = 1:sum(x[i, ])
)))) %>%
lapply(function(x)
return(data.frame(
S_n = as.numeric(x), N = 1:length(x)
)))
names(alphas) <- rownames(x)
alphas <- alphas %>% plyr::ldply(.id = "Curve")
alphas$type = "minor"
mean_alpha <-
data.frame(
Curve = "mean_alpha",
S_n = colMeans(as.matrix(vegan::rarefy(
x, 1:min(rowSums(x))
))),
N = 1:min(rowSums(x)),
type = "major"
)
gamma <-
data.frame(
Curve = "gamma",
S_n = as.numeric(vegan::rarefy(colSums(x), 1:sum(x))),
N = 1:sum(x),
type = "major"
)
out = alphas %>% full_join(mean_alpha, by = c("Curve", "S_n", "N", "type")) %>% full_join(gamma, by = c("Curve", "S_n", "N", "type"))
return(out)
}
splitgamma <-
function(x,
type = c("distinct", "random", "on_curve"),
n = round(sum(x) / 2),
iter = 150) {
if (type == "distinct") {
alpha1 = x
alpha2 = x
#index1=sample(1:length(x),length(x)/2)
#index2=setdiff(1:length(x),index1)
#alpha1[index1] = 0
#alpha2[index2] = 0
# alpha1[seq(1, length(x), 2)] = 0
# alpha2[seq(2, length(x), 2)] = 0
alpha2[1]=0
for (i in 2: length(x)){
if(sum(alpha1) > sum(alpha2)){
alpha1[i]=0
}else{
alpha2[i]=0
}
}
}
if (type == "random") {
alpha1 = sample_sad_N(x,N = n, replace = F)
alpha2 = x - alpha1
}
if (type == "on_curve") {
cases = lapply(1:iter, function(i)
sample_sad_N(x = x, N = n))
curves = lapply(cases, function(m)
rarefy(m, 1:n))
gamma_curve = rarefy(x, 1:n)
SS = sapply(curves, function(Sn) {
return(sum((gamma_curve - Sn) ^ 2))
})
alpha1 = cases[[order(SS)[1]]]
alpha2 = x - alpha1
}
return(rbind(alpha1, alpha2))
}
# Take subsamples of (Meta-)Community abundance vectors (individual based)
sample_sad_N<-function(x,N, replace=F){
sample_fun<-function(x,N, replace){
index=1:length(x)
y=rep(index,x)
samp<-data.frame(Species=sample(y, size = N, replace = replace)) %>%
group_by_all() %>%
count()
missing=data.frame(Species=setdiff(index, samp$Species))
samp=samp %>% full_join(missing, by = "Species") %>% arrange(Species) %>% pull(var = n)
samp[is.na(samp)]<-0
return(samp)
}
if(is.data.frame(x))x<- as.matrix(x)
if(is.vector(x)){
names=names(x)
x<-matrix(x, byrow = T, nrow = 1)
} else{
names<- dimnames(x)
}
if(any(rowSums(x)==0)) stop("Remove sites without individuals!")
out<-apply(x,1,sample_fun, replace = replace, N= N)
out<-t(out)
if(dim(out)[1]==1){
out= out[1,,drop=T]
names(out)= names
}else{
dimnames(out)<-names
}
return(out)
}
########################################################################################
# Styling
theme_set(theme_cowplot())
mytheme= theme(legend.position = "none",
axis.text=element_text(size=8),
axis.title=element_text(size=10),
plot.title = element_text(size=8,face = "bold"))
text_size= 8*5/ 14
#########################################################################
# Figure 1
# reference meta-community
# color palette
pal2<-viridisLite::magma(5)[c(1,4)]
base = as.integer(sim_sad(s_pool = 450, n_sim = 1000, sad_coef = list(cv_abund =2)) )
base_m = splitgamma(base, type = "on_curve",iter =300 )
base_curve <- rarefy_long(base_m)
base_curve <-base_curve %>% mutate(Curve = relevel(Curve, "gamma"))
base_plot <-
base_curve %>% filter(type == "major") %>% ggplot() +
geom_abline(intercept = specnumber(base), slope = 0, linetype=5, col=pal2[1])+
geom_abline(intercept = mean(specnumber(base_m)), slope = 0, linetype=5, col=pal2[2])+
geom_vline(xintercept = 250, linetype= "dashed", color ="grey")+
geom_line(aes(N, S_n, col = Curve),size = 1) +
annotate("text", size= text_size, x= 1000, y= 25,col=1, label=paste0("beta == ", round(specnumber(base)/mean(specnumber(base_m)),2)),parse = T ,hjust="right",vjust="center")+
annotate("text", size= text_size,x= 600, y= 25,col=1, label="beta[S[n]] == 1", nudge_y = -30,parse = T ,hjust="right", vjust="center")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300),expand = F)+
labs(title = "reference", x= "Individuals", y= "Rarefied richness")+
mytheme + scale_color_manual(values = pal2)
# fewer individuals
individuals = splitgamma(base, type = "on_curve", iter = 300,n = 500)[1, ]
individuals_m = splitgamma(individuals, type = "on_curve", iter = 200)
individuals_curve <- rarefy_long(individuals_m)
individuals_curve <-individuals_curve %>% mutate(Curve = relevel(Curve, "gamma"))
individuals_plot <-
individuals_curve %>% filter(type == "major") %>% ggplot(aes(N, S_n, col = Curve)) +
geom_abline(intercept = specnumber(individuals), slope = 0, linetype=5, col=pal2[1])+
geom_abline(intercept = mean(specnumber(individuals_m)), slope = 0, linetype=5,, col=pal2[2])+
geom_vline(xintercept = 250, linetype= "dashed", color ="grey")+
geom_line(data=base_curve %>% filter(type=="major", Curve=="gamma"), linetype= "dotted", size=1, col= "grey") +
geom_line(size = 1) +
annotate("text", size= text_size,x= 1000, y= 25,col=1, label=paste0("beta == ", round(specnumber(individuals)/mean(specnumber(individuals_m)),2)), nudge_y = -30,parse = T ,hjust="right", vjust="center")+
annotate("text", size= text_size,x= 600, y= 25,col=1, label="beta[S[n]] == 1", nudge_y = -30,parse = T ,hjust="right",vjust="center")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300),expand = F) +
labs(title = "fewer individuals", x= "Individuals", y= "Rarefied richness")+
mytheme + scale_color_manual(values = pal2)
# SAD change
pool = as.integer(sim_sad(s_pool = 80, n_sim = 1000, sad_coef = list(cv_abund = 2)) )# sim_ENS(30, 85, 1000)
pool_m = splitgamma(pool, type = "on_curve")
pool_curve <- rarefy_long(pool_m)
pool_curve <-pool_curve %>% mutate(Curve = relevel(Curve, "gamma"))
pool_plot <-
pool_curve %>% filter(type == "major") %>% ggplot(aes(N, S_n, col = Curve)) +
geom_abline(intercept = specnumber(pool), slope = 0, linetype=5, col=pal2[1])+
geom_abline(intercept = mean(specnumber(pool_m)), slope = 0, linetype=5, col=pal2[2])+
geom_vline(xintercept = 250, linetype= "dashed", color ="grey")+
geom_line(data=base_curve %>% filter(type=="major", Curve=="gamma"), linetype= "dotted", size=1, col= "grey") +
geom_line(size = 1) +
annotate("text", size= text_size,x= 1000, y=25,col=1, label=paste0("beta == ", round(specnumber(pool)/mean(specnumber(pool_m)),2)), nudge_y = -30,parse = T ,hjust="right", vjust="center")+
annotate("text", size= text_size,x= 600, y= 25,col=1, label="beta[S[n]] == 1", nudge_y = -30,parse = T ,hjust="right", vjust="center")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300),expand = F) +
labs(title = "smaller species pool", x= "Individuals", y= "Rarefied richness")+
mytheme + scale_color_manual(values = pal2)
# aggregation
space_m = splitgamma(base, type = "distinct")
space_curve <- rarefy_long(space_m)
space_curve <-space_curve %>% mutate(Curve = relevel(Curve, "gamma"))
space_plot <-
space_curve %>% filter(type == "major") %>% ggplot(aes(N, S_n, col = Curve)) +
geom_abline(intercept = specnumber(base), slope = 0, linetype=5, col=pal2[1])+
geom_abline(intercept = mean(rarefy(space_m, min(rowSums(space_m)))), slope = 0, linetype=5, col=pal2[2])+
geom_vline(xintercept = 250, linetype= "dashed", color ="grey")+
geom_line(size = 1) +
annotate("text", size= text_size,x= 1000, y= 25,col=1, label=paste0("beta == ", round(specnumber(base)/mean(specnumber(space_m)),2)), nudge_y = -30,parse = T ,hjust="right", vjust="center")+
annotate("text",size= text_size,x= 690, y= 25,col=1, label="beta[S[n]] == 1.38", nudge_y = -30,parse = T ,hjust="right",vjust="center")+
labs(title = "intraspecific aggregation", x= "Individuals", y= "Rarefied richness")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300),expand = F) +
mytheme + scale_color_manual(values = pal2)
Figure1 <- plot_grid(
NULL,
base_plot,
NULL,
pool_plot,
individuals_plot,
space_plot,
ncol = 3,
labels = c(NA, "A", NA, "B", "C", "D"),
align= "hv"
)
pdf("Figures/Figure1a.pdf",width = 15.6*0.393701,height = 10.4*0.393701,useDingbats = F)
Figure1
dev.off()
save_plot("Figures/Figure1.pdf",plot = Figure1, ncol = 3,nrow = 2,base_height = 5.2,base_asp = 1, units="cm")
ggsave("conceptual figures/Figure1.jpg",Figure1, width = 18, height = 12, units="cm")
########################################################################################################
# Figures 2 and 3
library(mobsim)
# color palette
pal <- viridisLite::viridis(10)[c(1,8)]
names(pal) <- c("large", "small")
base = sim_sad(s_pool = 100, n_sim = 1000, sad_coef = list(cv_abund = 2))
space_m = splitgamma(base, type = "distinct")
space_curve <- rarefy_long(space_m)
pool2 = sim_sad(s_pool = 500, n_sim = 1000, sad_coef = list(cv_abund =2))
space2_m = splitgamma(pool2, type = "distinct")
space2_curve <- rarefy_long(space2_m)
N1<- min(rowSums(space_m))
gamma_Sn1<-rarefy(base,N1)
alpha_Sn1<- mean(rarefy(space_m,N1))
cov_value= Chat(pool2,min(rowSums(space2_m)))
cov_value_small= Chat(base,min(rowSums(space_m)))
N_low<-round(invChat(base, cov_value))
SnC_gamma <-D0.hat(base, N_low)
SnC_alpha <- mean(apply(space_m,1,D0.hat,m=N_low))
betaC = SnC_gamma/SnC_alpha
beta_C_small<-beta_C(space_m, cov_value)
beta_C_large<-beta_C(space2_m, cov_value)
space_curve$Curve<-relevel(space_curve$Curve, "gamma")
space2_curve$Curve<-relevel(space2_curve$Curve, "gamma")
small_plot_C <-
ggplot() +
geom_line(size = 1) +
#geom_hline(yintercept = specnumber(base), linetype=5)+
geom_hline(yintercept =SnC_gamma, linetype=5, col= "darkgrey")+
geom_vline(xintercept = N_low, linetype = "dashed" , col= "darkgrey")+
geom_hline(yintercept =SnC_alpha, linetype=5, col= "darkgrey")+
geom_abline(slope = 1-cov_value, intercept = SnC_gamma - ((1-cov_value)*N_low), size=1, col= "darkgrey")+
geom_line(aes(N, S_n, linetype = Curve), data= filter(space_curve,type == "major"), size = 1,col= pal[2]) +
#geom_text(aes(x= N_low, y= 0), label=paste0("n = ", round(N_low,2)),nudge_x = 20, nudge_y = 10,parse = F ,hjust="left")+
geom_text(size= text_size,aes(x= 1000, y= SnC_alpha+4), label=paste0("beta[C] == ", round(beta_C_small,3)),nudge_x = , nudge_y = -25,parse = T ,hjust="right", vjust="bottom")+
labs(title="Small species pool\n(100 spp.)", x= "Individuals", y= "Rarefied richness")+ #"small pool - beta\nstandardised by coverage\nof large pool"
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300),expand = F) +
mytheme + theme(plot.title = element_text(colour = pal[2]))
small_plot_N <-
ggplot(data =NULL) +
geom_hline(yintercept =alpha_Sn1, linetype=5, col= "darkgrey")+
geom_vline(xintercept = min(rowSums(space_m)), linetype = "dashed", col= "darkgrey")+
geom_hline(yintercept = gamma_Sn1, linetype=5, col= "darkgrey")+
geom_abline(slope = 1-cov_value_small, intercept = gamma_Sn1 - ((1-cov_value_small)*N1), size=1, col= "darkgrey")+
geom_line(aes(N, S_n, linetype = Curve), data= filter(space_curve,type == "major"), size = 1, col= pal[2]) +
labs(title="Small species pool\n(100 spp.)", x= "Individuals", y= "Rarefied richness")+
#geom_text(aes(x= N1,y= 0), label=paste0("n = ", round(N1,2)),nudge_x = 20, nudge_y = 10, parse = F, hjust="left" )+
geom_text(size= text_size,aes(x= 1000, y= alpha_Sn1), label=paste0("beta[s[n]] == ", round(gamma_Sn1/alpha_Sn1,3)),nudge_x = , nudge_y = -25,parse = T ,hjust="right", vjust="bottom")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300), expand = F) +
mytheme + theme(plot.title = element_text(colour = pal[2]))
N_low2 <-min(rowSums(space2_m))
gamma_Sn<-D0.hat(pool2,N_low2)
alpha_Sn<- mean(apply(space2_m,1, D0.hat,N_low2))
large_plot_N <-
ggplot(data =NULL) +
geom_hline(yintercept =alpha_Sn, linetype=5, col= "darkgrey")+
geom_vline(xintercept = min(rowSums(space2_m)), linetype = "dashed", col= "darkgrey")+
geom_hline(yintercept = gamma_Sn, linetype=5, col= "darkgrey")+
geom_abline(slope = 1-cov_value, intercept = gamma_Sn - ((1-cov_value)*N_low2), size=1, col= "darkgrey")+
geom_line(aes(N, S_n, linetype = Curve), data= filter(space2_curve,type == "major"), size = 1, col= pal[1]) +
labs(title="Large species pool\n(500 spp.)", x= "Individuals", y= "Rarefied richness")+
#geom_text(aes(x= N_low2,y= 0), label=paste0("n = ", round(N_low2,2)),nudge_x = 20, nudge_y = 10, parse = F, hjust="left" )+
geom_text(size= text_size, aes(x= 1000, y= alpha_Sn), label=paste0("beta[s[n]] == ", round(gamma_Sn/alpha_Sn,3)), nudge_y = -25,parse = T ,hjust="right", vjust="bottom")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300), expand = F) +
mytheme + theme(plot.title = element_text(colour = pal[1]))
large_plot_C <-
ggplot() +
geom_hline(yintercept =alpha_Sn, linetype=5, col= "darkgrey")+
geom_vline(xintercept = min(rowSums(space2_m)), linetype = "dashed", col= "darkgrey")+
geom_hline(yintercept = gamma_Sn, linetype=5, col= "darkgrey")+
geom_abline(slope = 1-cov_value, intercept = gamma_Sn - ((1-cov_value)*N_low2), size=1, col= "darkgrey")+
geom_line(aes(N, S_n, linetype = Curve), data= filter(space2_curve,type == "major"), size = 1, col= pal[1]) +
labs(title="Large species pool\n(500 spp.)", x= "Individuals", y= "Rarefied richness")+
geom_text(size= text_size,aes(x= 1000, y= alpha_Sn), label=paste0("beta[C] == ", round(beta_C_large,3)), nudge_y = -25,parse = T ,hjust="right", vjust="bottom")+
coord_cartesian(xlim = c(0, 1050), ylim = c(0, 300), expand = F) +
mytheme +
theme(plot.title = element_text(colour = pal[1]))
# scaling relationship
dat1=tibble(N=1:(2*min(rowSums(space_m))),
C=map_dbl(N,function(N) Chat(colSums(space_m), N)),
beta_Sn = map_dbl(N,function(N)beta_SN(space_m, N)),
Species_pool= "small"
)
dat2=tibble(N=1:(2*min(rowSums(space2_m))),
C=map_dbl(N,function(N) Chat(colSums(space2_m), N)),
beta_Sn = map_dbl(N,function(N)beta_SN(space2_m, N)),
Species_pool= "large"
)
dat=bind_rows(dat1,dat2)
N_plot<-ggplot(data=dat)+
geom_line(aes(x=N, y=beta_Sn, col= Species_pool), size=1)+
theme(legend.position = "bottom")+
labs( x= "Individuals", y= expression(beta[s[n]]))+scale_color_manual(values = pal)+mytheme
C_plot<-ggplot(data=dat)+
geom_line(aes(x=C, y=beta_Sn, col= Species_pool),size=1)+
theme(legend.position = "bottom")+
labs( x= "Estimated coverage", y= expression(beta[C]))+
scale_color_manual(values = pal)+
geom_vline(xintercept = cov_value, linetype = "dashed", col= "darkgrey")+
mytheme
Figure2<-plot_grid(large_plot_N,small_plot_N, N_plot,ncol = 3, labels = "AUTO")
Figure3<-plot_grid(large_plot_C,small_plot_C, C_plot, ncol = 3, labels = "AUTO")
Figure2
Figure3
save_plot("Figures/Figure2.pdf",Figure2,ncol = 3,nrow = 1,base_height = 9,base_width = 5.2, units="cm" )
save_plot("Figures/Figure3.pdf",Figure3,ncol = 3,nrow = 1,base_height = 9,base_width = 5.2, units="cm" )
ggsave("conceptual figures/Figure2.jpg",Figure2, width = 18, height = 10, units="cm")
ggsave("conceptual figures/Figure3.jpg",Figure3, width = 18, height = 10, units="cm")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.